#!/bin/sh

. /opt/etc/torrent.conf

PATH=/bin:/sbin:/usr/bin:/opt/sbin:/opt/bin
export PATH


#################################################
## Debug

debug ()
{
    if [[ $DEBUG && $DEBUG -gt 0 ]]; then
	echo $*
    fi
}

#################################################
## The functions
_write_info()
{
    echo "STARTTIME=\"${STARTTIME}\"
ENDTIME=\"${ENDTIME}\"
TRIES=${TRIES:-0}
PROGRESS=\"${PROGRESS}\"
PID=${PID}
SCRAPE=\"${SCRAPE}\"
TORRENTNAME=\"${TORRENTNAME}\"" > "${TORRENT%/*}/.info"
}
    
_update_progress()
{
    for TORRENT in ${WORK}/*/*.torrent ${TARGET}/*/*.torrent.seeding ; do
	INFO="${TORRENT%/*}/.info"  
	if [ -f "${INFO}" ]; then
	    . "${INFO}"
	    LOG="${TORRENT%/*}/current.log"
	    PROGRESS=`tail -20 "${LOG}"|tr '\r' '\n'|grep "Download"|tail -1`  
	    _write_info
	fi
    done
}

# Can only start torrents in WORK or TARGET
_start_torrent()
{
    TORRENT="$1"
    if [ -f "${TORRENT%.seeding}.seeding" ]; then
	SEED="-s"
    else
	SEED=""
    fi

    DIRNAME="${TORRENT%/*}"
    cd "${DIRNAME}"    
#    echo "Starting torrent in ${DIRNAME}"
    [ -f ./.info ] && TMP="${TORRENT}" && . ./.info && TORRENT="${TMP}"
    nice nohup btget ${SEED} -t ${LOG_TIME} "${TORRENT}" 2>> current_error.log >> current.log &
    sleep 2 # Throttle for torrent to settle
    PID=$!
    [ -z "${STARTTIME}" ] && STARTTIME=`date +"${DATE_FORMAT}"`
    PROGRESS=""
    _write_info 

}

_stop_torrent ()
{
    TORRENT="$1"
    DIRNAME="${TORRENT%/*}"
    cd "${DIRNAME}"
    if [ -f ./.info ] ; then
	. ./.info
	kill -TERM ${PID} 
	[ -z "${ENDTIME}" ] && ENDTIME=`date +"${DATE_FORMAT}"`
	PID=""
	PROGRESS=`echo "${PROGRESS}" | cut -f 1 -d " "`
	_write_info
    fi
}

# Move selected torrent to work dir and start it
_enqueue()
{
    TORRENTNAME="${TORRENT%.torrent}"
    TORRENTNAME="${TORRENTNAME##*/}"
    mkdir -p "$WORK/$TORRENTNAME"                                               
    chmod 777 "$WORK/$TORRENTNAME" 
    mv "${TORRENT}" "$WORK/$TORRENTNAME"
    TORRENT="$WORK/$TORRENTNAME/${TORRENTNAME}.torrent"       
    _start_torrent "${TORRENT}"
}

# Suspend active torrent
_suspend ()
{
    _stop_torrent "${TORRENT}"
    mv "${TORRENT}" "${TORRENT}.suspended"
}

# Resume suspended torrent
_resume ()
{
    
    mv "${TORRENT}" "${TORRENT%.suspended}"
    _start_torrent "${TORRENT%.suspended}"
}

# Seed/unSeed DONE torrents
_seed ()
{
   # Double check
   if [ ! -f "${TARGET}${TORRENT#${TARGET}}" ] ; then
	echo -e "${BOLD}Can only seed already done torrents${NORMAL}"
	return
   fi
   
   if [ -f "${TORRENT%.seeding}" ]; then
	mv "${TORRENT}" "${TORRENT}.seeding"
	_start_torrent "${TORRENT}.seeding"
   else
	mv "${TORRENT}" "${TORRENT%.seeding}"
	_stop_torrent "${TORRENT%.seeding}"
   fi 
}

# Purge log files in target and cleanup removed
_purge ()
{
    LOG=`ls -1 $TARGET/*/*.log 2>/dev/null | head -n 1`
    if [ -z "${LOG}" ] ; then
	echo "No LOG to purge."
    else
      for f in $TARGET/*/*.log ; do
	DUMMY="${f%/*.log}"
	TORRENT="${DUMMY}/${DUMMY##*/}.torrent.seeding"
	if [ -f "${TORRENT}" ]; then
		echo -e "${WARN} $f not purged${NORMAL}"
	else
		echo "Purging $f"
		rm "$f"
	fi
      done
    fi
    
    REMOVED=`ls -1 $WORK/*/*.torrent.removed 2>/dev/null | head -n 1`
    if [ -n "${REMOVED}" ]; then
	for f in $WORK/*/*.torrent.removed ; do
		DIR=`dirname "$f"`
		echo "Purging $DIR"
		rm -fr "${DIR}"			
	done
    fi
}

# Instruct watchdog to stop/start all active torrents
_pause ()
{
    if [ -f "$WORK/.paused" ] ; then
	rm "$WORK/.paused"
	echo -e "${BOLD}Watchdog will resume torrents!${NORMAL}"
    else
	touch "$WORK/.paused"
	for TORRENT in ${WORK}/*/*.torrent ${TARGET}/*/*.torrent.seeding ; do
	    INFO="${TORRENT%/*}/.info"
	    if [ -f "${INFO}" ]; then
		. "${INFO}"
		kill -TERM ${PID}
                PROGRESS="paused ${PROGRESS}"
                PID=
                _write_info
	    fi
	done
	echo -e "${BOLD}All torrents killed!${NORMAL}"
    fi 
}

# Update scrape info for active and downloaded torrents                                                         
_scrape ()                                                                                                      
{                                                                                                               
  for TORRENT in ${WORK}/*/*.torrent ${TARGET}/*/*.torrent* ; do
	INFO="${TORRENT%/*}/.info"
	if [ -f "${INFO}" ]; then
	    . "${INFO}"
	    SCRAPE=`btlist -sq "${TORRENT}" | grep seeders` 
   	    _write_info 
	fi
  done
}                                                                                                               

_best_seed ()
{
   BEST=0
   if [ -n "`ls ${TARGET}/*/*.torrent 2>/dev/null | head -n 1`" ] ; then
   for TORRENT in ${TARGET}/*/*.torrent ; do
	INFO="${TORRENT%/*}/.info"
	if [ -f "${INFO}" ]; then
	    . "${INFO}"
	    QUOTIENT=`echo "${SCRAPE}" | sed '/seeders: [1-9]\{1,\}/s/seeders:.\([0-9]\{1,\}\) leechers: \([0-9]\{1,\}\).*/(\2000\/\1/;t;d'`
	    RATIO=$((QUOTIENT))
	    if [ ${RATIO} -gt ${BEST} ]; then
	        BESTTORRENT="${TORRENT}"
	        BESTSCRAPE="${SCRAPE}"
	        BEST=${RATIO}
	    fi
	fi
   done
   echo "#####################################"                                                            
   echo "### Best seed suggestion" 
   echo ""
   echo "${BESTTORRENT##*/}"
   echo "${BESTSCRAPE}"
   echo ""
   else
   echo -e "${BOLD}No torrents to suggest for seeding${NORMAL}"
   fi
}

                                          
# Sub for directory search
__find ()
{
    [ -n "${TORRENT}" ] && return
    
    FILEPAT="$1"
    if [ -n "`ls ${FILEPAT} 2>/dev/null | head -n 1`" ] ; then
	for i in $FILEPAT ; do
	    if [ $ID = $idx ]; then
		TORRENT="$i"
#		echo "Found $idx ${TORRENT}"
		return
	    fi
	    idx=$(($idx+1)) 
	done
    fi
}


# Search for torrent ID through directories.  Must be in sync with _list()
# When found TORRENT is set. Should always find!
_find ()
{
    idx=0 
    TORRENT=""
    __find "$WORK/*/*.torrent"
    __find "$TARGET/*/*.torrent.seeding"
    __find "$WORK/*/*.torrent.suspended"
    __find "$WORK/*/*.torrent.removed"
    __find "$SOURCE/*.torrent"
    __find "$TARGET/*/*.torrent" 
   [ -z "${TORRENT}" ] && echo "Assertion failed [ -z TORRENT ] in _find()" 
}

__list ()
{
    FILEPAT="$1"
    DESC="$2"
    
    if [ -n "`ls ${FILEPAT} 2>/dev/null | head -n 1`" ]
    then
	echo "#####################################"
	echo "### ${DESC} "
	for i in $FILEPAT
	do
	    DUMMY="${i%.torrent*}"
	    P="${i%/*}"
	    DUMMY=${DUMMY##*/}
	    echo -ne "${BOLD}${idx}) ${GREEN}$DUMMY${NORMAL}\t"
	    if [ -f "$P/.info" ] ; then
		. "$P/.info"
		echo -n "${PROGRESS}"
		[ -n "${PID}" ]  && echo -n " PID:${PID} "
		echo -n " Start: ${STARTTIME}"
		[ -n "${ENDTIME}" ] && echo -n " End: ${ENDTIME}"
		[ "${TRIES}" -gt 0 ] && echo -n " Tries: ${TRIES}"
   		[ -n "${SCRAPE}" ] && echo -n " ${SCRAPE}"
   		DL=`echo "${PROGRESS}" | sed 's/.*Download \([0-9]\{1,\}\)kbs.*/\1/;t;s/.*/0/'`
   		UL=`echo "${PROGRESS}" | sed 's/.*Upload \([0-9]\{1,\}\)kbs.*/\1/;t;s/.*/0/'`
   		download=$((${download}+${DL}))
   		upload=$((${upload}+${UL}))
   		STARTTIME=""
   		ENDTIME=""
   		PROGRESS=""
   		PID=""
   		SCRAPE=""
	    fi
	    echo ""
	    idx=`expr $idx + 1`
	done
	echo ""
    echo
    fi
}

_list ()
{
    idx=0
    download=0
    upload=0
    __list "$WORK/*/*.torrent" "Active"
    __list "$TARGET/*/*.torrent.seeding" "Seeding"
    echo -e "${BOLD}Total Download ${download}kbs Upload ${upload}kbs${NORMAL}"
    [ "x${ACTION}" = "x-u" -o "x${ACTION}" = "x-q" ] && return
    __list "$WORK/*/*.torrent.suspended" "Suspended" 
    __list "$WORK/*/*.torrent.removed" "Removed" 
    __list "$SOURCE/*.torrent" "Queued"
    __list "$TARGET/*/*.torrent" "Done" 
    
}

_root_check () {
	if  [ ${USER} != admin -a  ${USER} != root ]; then
	    echo "You must be root! Because of killing stuff"
	    return 1
	fi
	return 0
}

# Mark torrent as removed. Purge will do cleanup
_remove ()
{
    if [ -z "$ID" ] ; then
	echo -e "${WARN}Please select torrent first!${NORMAL}"
	return
    fi
   
    _find
   
   if [ -f "${TORRENT%.torrent.suspended}.torrent.suspended" ]; then
	mv "${TORRENT}" "${TORRENT%.suspended}.removed"
   else
	echo -e "${BOLD}Can only remove suspended torrents!${NORMAL}"
   fi
}

# Determine what to do? _resume|_suspend|_seed
_push()
{
    if [ -z "$ID" ] ; then
	echo -e "${BOLD}Please select torrent first!${NORMAL}"
	return
    fi
    _find
    
    if [ -f "${TORRENT%.suspended}.suspended" ]; then
       _resume
       return
    fi
   
    if [ -f "${WORK}${TORRENT#${WORK}}" ]; then
       if [ -f "${TORRENT%.torrent}.torrent" ]; then
	    _suspend
   	    return
       fi
       # Removed ? Not pushed
    fi
    
    if [ -f "${TARGET}${TORRENT#${TARGET}}" ]; then
       _seed
       return
    fi 
    
    if [ -f "${SOURCE}${TORRENT#${SOURCE}}" ]; then
       _enqueue
       return
    fi
    
    echo -e "${WARN}Nothing to push!${NORMAL}" 
}

# Show tail of the selected torrent log
_log ()
{
    if [ -z "$ID" ] ; then
	echo -e "${WARN}Please select torrent first!${NORMAL}"
	return
    fi
    _find
    DIR="${TORRENT%/*}"
    NAME="${TORRENT##*/}"
    echo -e "${BOLD}${NAME}${NORMAL}"
    tail -10 "${DIR}/current.log"
    SECONDS=`tail -10 "${DIR}/current.log" | tr '\r' '\n' | grep Time | tail -1 | cut -d " " -f 2`
    if [ -n "${SECONDS}" -a -x /opt/bin/date ]; then
      DATE=`/opt/bin/date -d "1970-01-01 UTC ${SECONDS} seconds" +"${DATE_FORMAT}"`
      echo -e "\n${BOLD}Last timestamp seen at ${DATE}${NORMAL}"
    fi
}

_info ()
{
    if [ -z "$ID" ] ; then
	echo -e "${BOLD}Please select torrent first!${NORMAL}"
	return
    fi
    _find
    echo "Status"
    echo ""
    btlist "${TORRENT}"
    echo ""
}

_help ()
{
    cat << __EOF__
This is quick explanation of the options:
-u	Updates active torrents status
-q	Quick show active torrents (without update)
-c n	Shows current.log of selected torrent
-s	All active torrent processing should stop/resume imediately
-p n	Push selected torrent to other queue
-l	Lists queued, active, suspended and completed torrents
-r n	Mark torrent for purging
-g	Purge removes all logs from completed torrents and clean removed torrents
-w 	Watchdog forces torrent_watchdog processing
-i n	Info shows selected torrent info ((file content and size)
-a	Update scrape info from tracker for downloaded torrents
-b	Suggest torrent with best (leeches/seeds) ratio for seeding
-ab	Equals -a -b
-h	More help needed ?
__EOF__
_root_check
}

#############################################
# MAIN PROCESS

QUERY_STRING=`echo "$QUERY_STRING" | sed 's/&/;/g'`
eval ${QUERY_STRING}
#export ACTION
#/opt/bin/printenv
ACTION="$1"
ID="$2"
case "${ACTION}" in
	-u) _update_progress ; _list ;;
	-q) _list ;;
	-c) _log ;;
	-p) _push  ;;
	-s) _pause ;;
        -r) _remove ;;
        -g) _purge ;;
        -w) torrent_watchdog ;;
        -i) _info ;;
        -l) _list ;;
        -a) _scrape ;;
        -b) _best_seed ;;
        -ab) _scrape ; _best_seed ;;
        -?) _help ;;
        *) _help ;;
esac
	

uptime
